home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / OSK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-30  |  24.6 KB  |  1,273 lines

  1. #ifdef OSK
  2. /* OS- and machine-dependent stuff for OS-9
  3.  * Copyright 1993 Brian A. Lantz, KO4KS
  4.  */
  5. #include "global.h"
  6. #include <conio.h>
  7. #include <dir.h>
  8. #include <dos.h>
  9. #include <io.h>
  10. #include <direct.h>
  11. #include <sys/stat.h>
  12. #include <string.h>
  13. #include <process.h>
  14. #include <fcntl.h>
  15. #include <alloc.h>
  16. #include <stdarg.h>
  17. #include <bios.h>
  18. #include "mbuf.h"
  19. #include "proc.h"
  20. #include "iface.h"
  21. #include "internet.h"
  22. #include "tty.h"
  23. #include "socket.h"
  24. #include "smtp.h"
  25. #include "cmdparse.h"
  26. #include "dirutil.h"
  27. #include "pc.h"
  28. #include <modes.h>
  29. #include "n8250.h"
  30. #include <sgstat.h>
  31. #include <time.h>
  32.  
  33. #define    CTLC    0x3
  34. #define    DEL    0x7f
  35.  
  36. #ifndef MSDOS
  37. static char rcsid[] OPTIONAL = "$Id: osk.c,v 1.15 1997/07/31 00:44:20 root Exp root $";
  38. #endif
  39.  
  40. static int kbchar (void);
  41. extern int Curdisp;
  42. extern struct proc *Display;
  43. FILE *Rawterm;
  44. volatile int Tick;
  45. int32 Clock;
  46. chtype MY_NORMAL;
  47. char Hashtab[256];
  48. extern char Eol[];
  49. extern int _gs_size(), _gs_gfd(), _gs_opt(), spawnvp();
  50. extern void _ss_opt(), clreol(), clrscr();
  51.  
  52. extern int Tracesession;
  53. extern char **environ;
  54. extern struct session *ScreenOwner;        /* Session currently displayed */
  55. extern struct session *Trace;
  56. extern int SYSback, SYSfore;
  57. extern TERMINAL *curses_in;
  58.  
  59. short UseCurses = 0;
  60. int FIX1, FIX2;
  61.  
  62. static char Ttbuf[BUFSIZ];
  63. static char Tsbuf[BUFSIZ];
  64.  
  65. /* Keyboard input buffer */
  66. #define    KBSIZE    256
  67. static struct {
  68.     int buf[KBSIZE];
  69.     int *wp;
  70.     int *rp;
  71.     int cnt;
  72. } Keyboard;
  73.  
  74. int
  75. errhandler(errval,ax,bp,si)
  76. int errval,ax,bp,si;
  77. {
  78.     return 3;    /* Fail the system call */
  79. }
  80.  
  81. struct sgbuf svbuf;
  82.  
  83. /* Called at startup time to set up console I/O, memory heap */
  84. void
  85. ioinit()
  86. {
  87. struct sgbuf sbuf;
  88.  
  89.     setbuf(stdout,Tsbuf);
  90.  
  91.     Rawterm = fdopen (dup(1), "w");
  92.     setbuf(Rawterm,Ttbuf);
  93.     if (UseCurses)    {
  94.         initscr();
  95.         if (has_colors ())
  96.             MY_NORMAL = (COLOR_BLACK <<20) + (COLOR_BLUE <<16);
  97.         else
  98.             MY_NORMAL = A_NORMAL;
  99.         keypad (stdscr, 1);
  100.     }
  101.         _gs_opt(0, &sbuf);
  102.         _gs_opt(0, &svbuf);
  103.         sbuf.sg_case = 0;
  104.         sbuf.sg_backsp = 0;
  105.         sbuf.sg_delete = 0;
  106.         sbuf.sg_echo = 0;
  107. /*        sbuf.sg_alf = 0;    */
  108.         sbuf.sg_nulls = 0;
  109.         sbuf.sg_pause = 0;
  110.         sbuf.sg_page = 0;
  111.         sbuf.sg_bspch = 0;
  112.         sbuf.sg_dlnch = 0;
  113.         sbuf.sg_eorch = 0;
  114.         sbuf.sg_eofch = 0;
  115.         sbuf.sg_rlnch = 0;
  116.         sbuf.sg_dulnch = 0;
  117.         sbuf.sg_psch = 0;
  118. /*      sbuf.sg_kbich = 0;
  119.         sbuf.sg_kbach = 0;    */
  120.         sbuf.sg_bsech = 0;
  121.         sbuf.sg_bellch = 0;
  122. /*      sbuf.sg_xon = 0;
  123.         sbuf.sg_xoff = 0;
  124.         sbuf.sg_tabcr = 0;
  125.         sbuf.sg_tabsiz = 0;    */
  126.         _ss_opt(0, &sbuf);
  127.  
  128.     /* Initialize keyboard queue */
  129.     Keyboard.rp = Keyboard.wp = Keyboard.buf;
  130.  
  131. }
  132. /* Called just before exiting to restore console state */
  133. void
  134. iostop()
  135. {
  136.     struct iface *ifp,*iftmp;
  137.     void (**fp)();
  138.  
  139.         _ss_opt(0, &svbuf);
  140.     for(ifp = Ifaces;ifp != NULLIF;ifp = iftmp){
  141.         iftmp = ifp->next;
  142.         if_detach(ifp);
  143.     }
  144.     /* Call list of shutdown functions */
  145.     for(fp = Shutdown;*fp != NULLVFP;fp++)
  146.         (**fp)();
  147.     if (UseCurses)    {
  148.         wattrset (stdscr,MY_NORMAL);
  149.         clear ();
  150.         wrefresh (stdscr);
  151.         endwin();
  152.         UseCurses = 0;
  153.     }
  154. }
  155. #ifdef SHELL
  156. /* Spawn subshell */
  157. int
  158. doshell(argc,argv,p)
  159. int argc;
  160. char *argv[];
  161. void *p;
  162. {
  163. char *command;
  164. int ret;
  165. char *myargv[3];
  166.  
  167.     if(argc == 1) {
  168.         if((command = getenv("SHELL")) == NULLCHAR)
  169.             command = "SHELL";
  170.         puts ("Type 'LOGOUT' (or press <ESC>) to return to TNOS");
  171.         myargv[0] = command;
  172.         myargv[1] = "-p=\"\lTNOS-OS9: \"";
  173.         myargv[2] = (char *) 0;
  174.          ret = spawnvp(P_WAIT,command,myargv);
  175.     } else 
  176.         ret = spawnvp(P_WAIT,argv[1],(argv + 1));
  177.     return ret;
  178. }
  179. #endif
  180.  
  181. #ifdef ALLCMD
  182. /* Spawn mailer as subshell */
  183. int
  184. dobmail(argc,argv,p)
  185. int argc;
  186. char *argv[];
  187. void *p;
  188. {
  189.     char *command;
  190.     int ret;
  191.  
  192.     if((command = getenv("MAILER")) == NULLCHAR)
  193.         command = "BM";
  194.     ret = spawnvp(P_WAIT,command,argv);
  195.  
  196.     smtptick(NULL);        /* tickle smtp to send any mail */
  197.     return ret;
  198. }
  199. #endif /*ALLCMD*/
  200.  
  201. /* Keyboard interrupt handler */
  202. void
  203. kbint()
  204. {
  205. int sig = 0;
  206. int c;
  207.  
  208.     while((c = kbraw()) != -1 && Keyboard.cnt < KBSIZE){
  209.         sig = 1;
  210.         *Keyboard.wp++ = c;
  211.         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  212.             Keyboard.wp = Keyboard.buf;
  213.         Keyboard.cnt++;
  214. #ifdef SCREENSAVER
  215.         sskick();
  216. #endif
  217.     }
  218.     if(sig){
  219.         ksignal(&Keyboard,0);
  220.     }
  221. }
  222.  
  223. static int
  224. kbchar()
  225. {
  226. int c;
  227.  
  228.     while(Keyboard.cnt == 0)
  229.         kwait(&Keyboard);
  230.     Keyboard.cnt--;
  231.     c = *Keyboard.rp++;
  232.     if(Keyboard.rp == &Keyboard.buf[KBSIZE])
  233.         Keyboard.rp = Keyboard.buf;
  234.     return (c);
  235. }
  236. /* Flush the raw terminal output */
  237. void
  238. rflush()
  239. {
  240.     if (!UseCurses)
  241.         fflush(Rawterm);
  242.     else    {
  243. #ifdef SCREENSAVER
  244.         if (!ssenabled())    {
  245. #endif
  246.             if (ScreenOwner->split)
  247.                 wrefresh (ScreenOwner->screen->splitwin);
  248. /*            leaveok (ScreenOwner->screen->textwin, 0);    */
  249.             wrefresh (ScreenOwner->screen->textwin);
  250.             if (ScreenOwner->screen->statline)
  251.                 wrefresh (ScreenOwner->screen->statwin);
  252. #ifdef SCREENSAVER
  253.         }
  254. #endif
  255.     }
  256. }
  257.  
  258. #ifdef ALLCMD
  259. struct funcstr {
  260.     short fkey;
  261.     char alloced;
  262.     char *fvalue;
  263. };
  264.  
  265. struct funcstr fkeys[] = {
  266.     KEY_BTAB,0,NULLCHAR,        /* tab + shift */
  267.     KEY_F1,1,NULLCHAR,          /* F1 */
  268.     KEY_F2,1,NULLCHAR,          /* F2 */
  269.     KEY_F3,1,NULLCHAR,          /* F3 */
  270.     KEY_F4,1,NULLCHAR,          /* F4 */
  271.     KEY_F5,0,NULLCHAR,        /* F5 */
  272.     KEY_F6,0,NULLCHAR,        /* F6 */
  273.     KEY_F7,0,NULLCHAR,        /* F7 */
  274.     KEY_F8,0,NULLCHAR,        /* F8 */
  275.     KEY_F9,0,NULLCHAR,        /* F9 */
  276.     KEY_F10,0,NULLCHAR,        /* F10 */
  277.     KEY_HOME,1,NULLCHAR,        /* home*/
  278.     KEY_UP,1,"\033[A",        /* up arrow*/
  279.     KEY_PPAGE,1,NULLCHAR,        /* pgup */
  280.     KEY_LEFT,1,"\033[D",        /* left arrow */
  281.     KEY_RIGHT,1,"\033[C",        /* right arrow */
  282.     KEY_END,1,NULLCHAR,        /* end */
  283.     KEY_DOWN,1,"\033[B",        /* down arrow */
  284.     KEY_NPAGE,1,NULLCHAR,        /* pgdn */
  285.     KEY_IC,1,NULLCHAR,        /* ins */
  286.     KEY_DC,1,NULLCHAR,        /* del */
  287.     KEY_SF1,0,NULLCHAR,        /* F1 + shift*/
  288.     KEY_SF2,0,NULLCHAR,        /* F2 + shift*/
  289.     KEY_SF3,0,NULLCHAR,        /* F3 + shift*/
  290.     KEY_SF4,0,NULLCHAR,        /* F4 + shift*/
  291.     KEY_SF5,0,NULLCHAR,        /* F5 + shift*/
  292.     KEY_SF6,0,NULLCHAR,        /* F6 + shift*/
  293.     KEY_SF7,0,NULLCHAR,        /* F7 + shift*/
  294.     KEY_SF8,0,NULLCHAR,        /* F8 + shift*/
  295.     KEY_SF9,0,NULLCHAR,        /* F9 + shift*/
  296.     KEY_SF10,0,NULLCHAR,        /* F10 + shift*/
  297.     KEY_CTL_F1,0,NULLCHAR,        /* F1 + control*/
  298.     KEY_CTL_F2,0,NULLCHAR,        /* F2 + control*/
  299.     KEY_CTL_F3,0,NULLCHAR,        /* F3 + control*/
  300.     KEY_CTL_F4,0,NULLCHAR,        /* F4 + control*/
  301.     KEY_CTL_F5,0,NULLCHAR,        /* F5 + control*/
  302.     KEY_CTL_F6,0,NULLCHAR,        /* F6 + control*/
  303.     KEY_CTL_F7,0,NULLCHAR,        /* F7 + control*/
  304.     KEY_CTL_F8,0,NULLCHAR,        /* F8 + control*/
  305.     KEY_CTL_F9,0,NULLCHAR,        /* F9 + control*/
  306.     KEY_CTL_F10,0,NULLCHAR,        /* F10 + control*/
  307.     KEY_ALTKBD+KEY_F1,0,NULLCHAR,    /* F1 + alt*/
  308.     KEY_ALTKBD+KEY_F2,0,NULLCHAR,    /* F2 + alt*/
  309.     KEY_ALTKBD+KEY_F3,0,NULLCHAR,    /* F3 + alt*/
  310.     KEY_ALTKBD+KEY_F4,0,NULLCHAR,    /* F4 + alt*/
  311.     KEY_ALTKBD+KEY_F5,0,NULLCHAR,    /* F5 + alt*/
  312.     KEY_ALTKBD+KEY_F6,0,NULLCHAR,    /* F6 + alt*/
  313.     KEY_ALTKBD+KEY_F7,0,NULLCHAR,    /* F7 + alt*/
  314.     KEY_ALTKBD+KEY_F8,0,NULLCHAR,    /* F8 + alt*/
  315.     KEY_ALTKBD+KEY_F9,0,NULLCHAR,    /* F9 + alt*/
  316.     KEY_ALTKBD+KEY_F10,0,NULLCHAR,    /* F10 + alt*/
  317.     KEY_SEND,0,NULLCHAR,        /* end  + ctl */
  318.     KEY_SR,0,NULLCHAR,        /* pgup + ctl */
  319.     KEY_SHOME,0,NULLCHAR,        /* home + ctl */
  320.     KEY_SF,0,NULLCHAR,        /* pgdn + ctl */
  321.       0,0,NULLCHAR
  322. };
  323.  
  324. char Leftover = 0;
  325. char *Nextkey;
  326. #endif /*ALLCMD*/
  327.  
  328. /* Read characters from the keyboard, translating them to "real" ASCII.
  329.  * If none are ready, block. The F-10 key is special; translate it to -2.
  330.  */
  331. #ifdef ALLCMD
  332. int
  333. kbread()
  334. {
  335. int c,i,j;
  336.  
  337.     if((c = Leftover) != 0)  {
  338.         Leftover = *Nextkey++;
  339.         return c;
  340.     }
  341.     c = kbchar();
  342.     if (c < 256)
  343.         return (c);
  344.     switch (c)    {
  345.         case KEY_UP:    /* UP ARROW key (used as previous history command) */
  346.             if(Current == Command) {   
  347.                 c = UPARROW;
  348.                 break;
  349.             }
  350.             goto all;
  351.         case KEY_DOWN:    /* DOWN ARROW key (used as next history command) */
  352.             if(Current == Command) {
  353.                 c = DNARROW;
  354.                 break;
  355.             }
  356.             goto all;
  357.             case KEY_F10:    /* F-10 key (used as command-mode escape) */
  358.             if(fkeys[10].fvalue == NULLCHAR){
  359.                 c = -2;
  360.                 break;
  361.             }
  362.                 goto all;
  363.             case KEY_IC:   /* INSERT key (used as status line toggle) */
  364.             if(fkeys[19].fvalue == NULLCHAR){
  365.                 c = -105;
  366.                 break;
  367.             }
  368.             goto all;
  369.             case KEY_DC:   /* DELETE key (used as flow mode toggle) */
  370.             if(fkeys[20].fvalue == NULLCHAR){
  371.                 c = -106;
  372.                 break;
  373.             }
  374.             goto all;
  375.             case KEY_HOME:   /* HOME key (used to kick this session) */
  376.             if(fkeys[11].fvalue == NULLCHAR){
  377.                 c = -107;
  378.                 break;
  379.             }
  380.             goto all;
  381.             case KEY_END:   /* END key (used to kill this session) */
  382.             if(fkeys[16].fvalue == NULLCHAR){
  383.                 c = -108;
  384.                 break;
  385.             }
  386.             goto all;
  387.             case KEY_PPAGE:   /* PGUP key (used to toggle to previous session) */
  388.             if(fkeys[13].fvalue == NULLCHAR){
  389.                 c = -109;
  390.                 break;
  391.             }
  392.             goto all;
  393.             case KEY_NPAGE:   /* PGDN key (used to toggle to next session) */
  394.             if(fkeys[18].fvalue == NULLCHAR){
  395.                 c = -110;
  396.                 break;
  397.             }
  398.             goto all;
  399. #ifdef notyet
  400.         case KEY_BACKSPACE:
  401.             c = '\b';
  402.             goto all;
  403.         case KEY_ENTER:
  404.             c = '\n';
  405.             goto all;
  406. #endif
  407.             default:    /* Dunno what it is */
  408. all:
  409.             if(c > KEY_F0 && c < KEY_F10) {  /* F1 to F9 */
  410.                 if(fkeys[c-KEY_F1+1].fvalue == NULLCHAR) {
  411.                     c = ((c - KEY_F1) + 3) * -1; /* NO fkey defined - WG7J */
  412.                     break;
  413.                 }
  414.             }
  415.             for(i=0;(j = fkeys[i].fkey) != 0;i++)
  416.                 if(j == c) {
  417.                     Nextkey = fkeys[i].fvalue;
  418.                     if(Nextkey == NULLCHAR) {
  419.                         c = -1;
  420.                         return c;
  421.                     }
  422.                     /* If first char of fvalue is '~'
  423.                      * switch to command session.
  424.                      */
  425.                     if((c = *Nextkey++) == '~') {
  426.                         c = -2;
  427.                         Leftover = *Nextkey++;
  428.                     } else {
  429.                         if(c != 0)
  430.                             Leftover = *Nextkey++;
  431.                         else
  432.                             c = -1;
  433.                     }
  434.                     return c;
  435.                 }
  436.             c = -1;
  437.         }
  438.     return c;
  439. }
  440. #else /*ALLCMD*/
  441.  
  442. int
  443. kbread()
  444. {
  445. int c;
  446.  
  447.     c = kbchar();
  448.     if(Current == Command) {    /* Check for command recall */
  449.         if(c == KEY_UP)     /* UP arrow */
  450.             return UPARROW;
  451.         if(c == KEY_DOWN)     /* DOWN arrow */
  452.             return DNARROW;
  453.     }
  454.     if (c < 256)
  455.         return (c);
  456.     switch(c)    {
  457.         case KEY_F10:        /* F-10 key (used as command-mode escape) */
  458.             c = -2;
  459.             break;
  460.         case KEY_DL:        /* DEL key */
  461.             c = 0x7f;
  462.             break;
  463.         case KEY_BACKSPACE:
  464.             c = '\b';
  465.             break;
  466.         case KEY_ENTER:
  467.             c = '\n';
  468.             break;
  469.         default:        /* Dunno what it is */
  470.             if(c > KEY_F0 && c < KEY_F10)    /* F1 to F9 */
  471.                 c = ((c - KEY_F1) + 3) * -1;
  472.             else
  473.                 c = -1;
  474.     }
  475.         return c;
  476. }
  477.  
  478. #endif /*ALLCMD*/
  479.  
  480. #ifdef ALLCMD
  481. int
  482. dofkey(argc,argv,p)
  483. int argc;
  484. char *argv[];
  485. void *p;
  486. {
  487. int c,i,j;
  488. char *q, *r;
  489. char str[100];
  490.  
  491.     if(argc == 1) {
  492.        tprintf("     key   num    key    num    key    num    key    num   key    num\n");
  493.        tprintf("     f1    265    sf1    281    cf1    297    af1    393   pgup   339\n");
  494.        tprintf("     f2    266    sf2    282    cf2    298    af2    394   pgdn   338\n");
  495.        tprintf("     f3    267    sf3    283    cf3    299    af3    395   home   262\n");
  496.        tprintf("     f4    268    sf4    284    cf4    300    af4    396   end    360\n");
  497.        tprintf("     f5    269    sf5    285    cf5    301    af5    397   arup   259\n");
  498.        tprintf("     f6    270    sf6    286    cf6    302    af6    398   ardn   258\n");
  499.        tprintf("     f7    271    sf7    287    cf7    303    af7    399   ar l   260\n");
  500.        tprintf("     f8    272    sf8    288    cf8    304    af8    400   ar r   261\n");
  501.        tprintf("     f9    273    sf9    289    cf9    305    af9    401   ins    331\n");
  502.        tprintf("     f10   274    sf10   290    cf10   306    af10   402   del    330\n");
  503.        tprintf("     cpgup 337    cpgdn  336    chome  391    cend   386   stab   353\n\n");
  504.        tprintf("usage: fkey <key number> [<value> | \"string\"]\n");
  505.        return 0;
  506.     }
  507.  
  508.     c = atoi(argv[1]);
  509.     if(c < KEY_BREAK || c > KEY_SF20+KEY_ALTKBD) {
  510.         tprintf("fkey number out of range.\n");
  511.         return 1;
  512.     }
  513.  
  514.     for(j = 0;(i = fkeys[j].fkey) != 0; j++)
  515.         if(i == c) 
  516.             break;
  517.  
  518.     if(i == 0){
  519.         tprintf("fkey number not found\n");
  520.         return 1;
  521.     }
  522.  
  523.     if(argc == 2) {
  524.         q = fkeys[j].fvalue;
  525.         r = str;
  526.         if(q == NULLCHAR)
  527.             tprintf("fkey %d has no assigned value.\n",c);
  528.         else {
  529.             while(*q)
  530.                 if(*q < ' ') { /* This is ASCII dependent !! */
  531.                     *r++ = '^';
  532.                     *r++ = *q++ + 0x40;
  533.                 } else
  534.                     *r++ = *q++;
  535.             *r = '\0';
  536.             tprintf("fkey = %s\n",str);
  537.         }
  538.         return 0;
  539.     }
  540.  
  541.     if(argc == 3) {
  542.         if(fkeys[j].alloced)
  543.             fkeys[j].alloced = 0;
  544.         else
  545.             if(fkeys[j].fvalue != NULLCHAR)
  546.                 free(fkeys[j].fvalue);
  547.  
  548.         r = str;
  549.         q = argv[2];
  550.         while(*q){
  551.             if(*q == '^'){    /* ^ gives control char next */
  552.                 q++;
  553.                 if(*q == '^') {
  554.                     *r++ = *q++; /* No, he wants a ^ */
  555.                 } else {
  556.                     *r++ = *q++ & 0x1f;
  557.                 }
  558.             } else
  559.                 *r++ = *q++;
  560.         }
  561.         *r = '\0';
  562.         fkeys[j].fvalue = strdup(str);
  563.     }
  564.     return 0;
  565. }
  566. #endif /*ALLCMD*/
  567.  
  568. /* Called on each NOS clock tick. Signal a clock tick to the timer process.
  569.  */
  570. void
  571. ctick()
  572. {
  573.     Tick++;
  574.     ksignal(&Tick,1);
  575. }
  576. /* Called from the timer process on every tick. NOTE! This function
  577.  * can NOT be called at interrupt time because it calls the BIOS
  578.  */
  579. void
  580. pctick()
  581. {
  582.     Clock = clock() / 2;
  583. }
  584.  
  585. /* Convert a pointer to a long integer */
  586. long
  587. ptol(p)
  588. void *p;
  589. {
  590.     return ((long) p);
  591. }
  592.  
  593. void
  594. sysreset()
  595. {
  596. #asm
  597.     move.l    0,a7
  598.     move.l    4,a0
  599.     jmp     (a0)
  600. #endasm
  601. }
  602.  
  603. extern unsigned char SCREENwidth, SCREENlength;
  604. extern int STATLINE;
  605.  
  606. void
  607. newscreen(sp)
  608. struct session *sp;
  609. {
  610. struct session *old;
  611.  
  612.     if(sp != NULLSESSION)    {
  613.         sp->screen = callocw(1,sizeof(struct screen));
  614.         sp->screen->statline = STATLINE;
  615.         sp->screen->attr = MY_NORMAL >> 16;
  616.         if (UseCurses)        {
  617.             sp->screen->win = sp->screen->textwin = newwin (24 - (sp->split * 2), 80, 0, 0);
  618.             if (sp->split)    {
  619.                 sp->screen->splitwin = newwin (2, 80, 22, 0);
  620.                 leaveok (sp->screen->splitwin, 1);
  621.                 if (!has_colors())
  622.                     wattrset (sp->screen->splitwin, A_REVERSE);
  623.                 else
  624.                     wattrset (sp->screen->splitwin, (SYSback >> 4)+(SYSfore << 4));
  625.                 werase (sp->screen->splitwin);
  626.                 waddch (sp->screen->splitwin, '_');
  627.                 wmove (sp->screen->splitwin, 0, 0);
  628.             }
  629.             scrollok (sp->screen->win, 1);
  630.             if (has_colors())
  631.                 sp->screen->attr = (SYSback+SYSfore) >> 16;
  632.             wattrset (sp->screen->win, sp->screen->attr << 16);
  633.             wclear (sp->screen->win);
  634.         }
  635.     }
  636. }
  637. void
  638. freescreen(sp)
  639. struct session *sp;
  640. {
  641.     if(sp == NULLSESSION || sp->screen == NULLSCREEN)
  642.         return;
  643.     if (UseCurses)    {
  644.         delwin (sp->screen->textwin);
  645.         if (sp->split)
  646.             delwin (sp->screen->splitwin);
  647.         if (sp->screen->statline)
  648.             delwin (sp->screen->statwin);
  649.     }
  650.     free((char *)sp->screen);
  651. }
  652.  
  653.  
  654. /* Save specified session screen and resume console screen */
  655. void
  656. swapscreen(old,new)
  657. struct session *old,*new;
  658. {
  659.     if (old != NULLSESSION && UseCurses)
  660.         rflush ();
  661.     ScreenOwner = new;
  662.     if (new != NULLSESSION && UseCurses)        {
  663.         touchwin (new->screen->textwin);
  664.         if (new->split)
  665.             touchwin (new->screen->splitwin);
  666.         if (new->screen->statwin)
  667.             touchwin (new->screen->statwin);
  668.         displayStatLine (0, 1, 0);
  669.         rflush ();
  670.     }
  671.     alert(Display,1);    /* Wake him up */
  672. }
  673.  
  674. void
  675. display(i,v1,v2)
  676. int i;
  677. void *v1;
  678. void *v2;
  679. {
  680.     int c;
  681.     struct session *sp;
  682.  
  683.     /* This is very tricky code. Because the value of "Current" can
  684.      * change any time we do a kwait, we have to be careful to detect
  685.      * any change and go back and start again.
  686.      */
  687.     for(;;){
  688.         sp = Current;
  689.  
  690.         if(sp->morewait){
  691.             kwait(&sp->row);
  692.             if(sp != Current || sp->row <= 0){
  693.                 /* Current changed value, or the user
  694.                  * hasn't really hit a key
  695.                  */
  696.                 continue;
  697.             }
  698.             /* Erase the prompt */
  699.             if (UseCurses)    {
  700. #ifdef SCREENSAVER
  701.                 sskick();
  702. #endif
  703.                 waddstr(ScreenOwner->screen->win,"\b\b\b\b\b\b\b\b        \b\b\b\b\b\b\b\b");
  704.             } else
  705.                 fprintf(Rawterm,"\b\b\b\b\b\b\b\b        \b\b\b\b\b\b\b\b");
  706.             rflush();
  707.         }
  708.         sp->morewait = 0;
  709.         if((c = rrecvchar(sp->output)) == EOF){
  710.             /* the alert() in swapscreen will cause this to
  711.              * return EOF when current changes
  712.              */
  713.             kwait(NULL);    /* Prevent a nasty loop */
  714.             continue;
  715.         }
  716. #ifdef SCREENSAVER
  717.         sskick ();
  718. #endif
  719.         if (c == '\l')
  720.             continue;
  721.         if(c == '\n'){
  722.             cputs(Eol);
  723. /*            clreol();    */
  724.         } else
  725.             putch(c);
  726.         /* Fix by Ron Murray, vk6zjm */
  727.         if(sp->record != NULLFILE)      /* Don't save CR if ascii mode */
  728.             if (c != '\l' || sockmode(sp->output, -1) != SOCK_ASCII)
  729.                 putc(c,sp->record);
  730.         if(sp->flowmode && c == '\n' && --sp->row <= 0){
  731.             if (!UseCurses)
  732.             fprintf(Rawterm,"--More--");
  733.         else    {
  734. #ifdef SCREENSAVER
  735.             sskick();
  736. #endif
  737.             waddstr(ScreenOwner->screen->win,"--More--");
  738.         }
  739.         sp->morewait = 1;
  740.         }
  741.     }
  742. }
  743. /* Return time since startup in milliseconds. */
  744. int32
  745. msclock()
  746. {
  747.     return Clock * MSPTICK;
  748. }
  749. /* Return clock in seconds */
  750. int32
  751. secclock()
  752. {
  753.     return Clock * MSPTICK / 1000L;
  754. }
  755.  
  756. /* same as getenv(), but return "" instead of NULL when it does not exist */
  757. char *getnenv (name)
  758. char *name;
  759. {
  760.     char *rv;
  761.  
  762.     if ((rv = getenv(name)) == NULL)
  763.          rv = "";            /* NULL replaced by "" */
  764.  
  765.     return rv;
  766. }
  767.  
  768. int TNOS_68KAlarm;
  769.  
  770. int
  771. housekeeping (sig)
  772. int sig;
  773. {
  774.     switch (sig)    {
  775.         case 3:        if (UseCurses)    {
  776.                     endwin();
  777.                     UseCurses = 0;
  778.                     clrscr();
  779.                 }
  780.                 _ss_opt(0, &svbuf);    
  781.                 exit (0);
  782.                 break;
  783.         case 6809:    ctick();
  784.         default:    break;
  785.     }
  786. }
  787.  
  788.  
  789. void
  790. oskinit()
  791. {
  792.     intercept (housekeeping);
  793.     TNOS_68KAlarm = alm_cycle (6809, 2);
  794. }
  795.  
  796.  
  797. _dos_getfileattr (file, attr)
  798. char *file;
  799. unsigned *attr;
  800. {
  801. FILE *fp;
  802. struct fildes b;
  803.  
  804.     if ((fp = fopen (file, "r")) == NULLFILE)
  805.         if ((fp = fopen (file, "d")) == NULLFILE)
  806.             return -1;
  807.     _gs_gfd (fileno(fp), &b, sizeof (struct fildes));
  808.     fclose (fp);
  809.     *attr = (b.fd_att & 0x80) ? FA_DIREC : 0;
  810.     return 0;
  811. }
  812.  
  813. int
  814. putch (c)
  815. int c;
  816. {
  817. static short lastwasCR = 0;
  818.     
  819.     if (c == '\l' && !lastwasCR)    {
  820.         FIX1++;
  821.         c = '\n';
  822.     }
  823.     lastwasCR = (c == '\n') ? 1 : 0;
  824.     if (!UseCurses)    {
  825.         if (c != '\l')
  826.             putchar (c);
  827.         return 0;
  828.     }
  829.     if (c == '\007')
  830.         beep ();
  831.     else    {
  832. #ifdef SCREENSAVER
  833.         sskick();
  834. #endif
  835.         waddch (ScreenOwner->screen->win, c);
  836.         if (c == '\n')    {
  837.             waddch (ScreenOwner->screen->win, '\l');
  838.             rflush ();
  839.         }
  840.     }
  841.     return 0;
  842. }
  843.  
  844. void
  845. highvideo ()
  846. {
  847. int back, fore;
  848.  
  849.     if (UseCurses && has_colors())    {
  850. #ifdef SCREENSAVER
  851.         sskick();
  852. #endif
  853.         fore = (ScreenOwner->screen->attr & 0x0f);
  854.         fore = (fore) ? fore - 1 : 7;
  855.         fore <<= 16;
  856.         back = (ScreenOwner->screen->attr & 0xf0) << 16;
  857.         wattrset (ScreenOwner->screen->win, back+fore);
  858.     }
  859. }
  860.  
  861. void
  862. lowvideo()
  863. {
  864. int back, fore;
  865.  
  866.     if (UseCurses && has_colors())    {
  867. #ifdef SCREENSAVER
  868.         sskick();
  869. #endif
  870.         wattrset (ScreenOwner->screen->win, ScreenOwner->screen->attr << 16);
  871.     }
  872. }
  873.  
  874. int
  875. cputs (str)
  876. char *str;
  877. {
  878.     while (*str)
  879.         putch (*str++);
  880.     return 0;
  881. }
  882.  
  883. void
  884. clreol ()
  885. {
  886.     if (UseCurses)    {
  887. #ifdef SCREENSAVER
  888.         sskick ();
  889. #endif
  890.         wclrtoeol (ScreenOwner->screen->win);
  891.     }
  892. }
  893.  
  894. void
  895. clrscr ()
  896. {
  897. int k;
  898.  
  899.     if (UseCurses)    {
  900. #ifdef SCREENSAVER
  901.         sskick();
  902. #endif
  903.         werase (ScreenOwner->screen->win);
  904.         wrefresh (ScreenOwner->screen->win);
  905.     } else    {
  906.         for (k = 0; k < 24; k++)
  907.             putchar ('\n');
  908.     }
  909. }
  910.  
  911. int
  912. wherey ()
  913. {
  914. int y = 0, x;
  915.  
  916.     if (UseCurses)    {
  917. #ifdef SCREENSAVER
  918.         sskick();
  919. #endif
  920.         getyx (ScreenOwner->screen->win, y, x);
  921.     }
  922.     return y;
  923. }
  924.  
  925. int
  926. wherex ()
  927. {
  928. int y, x = 0;
  929.  
  930.     if (UseCurses)    {
  931. #ifdef SCREENSAVER
  932.         sskick();
  933. #endif
  934.         getyx (ScreenOwner->screen->win, y, x);
  935.     }
  936.     return x;
  937. }
  938.  
  939. void
  940. gotoxy (x, y)
  941. int x, y;
  942. {
  943.     if (UseCurses)    {
  944. #ifdef SCREENSAVER
  945.         sskick();
  946. #endif
  947.         wmove (ScreenOwner->screen->win, y, x);
  948.     }
  949. }
  950.  
  951. void
  952. hardretn (i)
  953. int i;
  954. {
  955. }
  956.  
  957. unsigned long
  958. farcoreleft ()
  959. {
  960.     return (coreleft());
  961. }
  962.  
  963. int
  964. fputc (c, fp)
  965. int c;
  966. FILE *fp;
  967. {
  968.     return (putc (c, fp));
  969. }
  970.  
  971. void
  972. _getdate (datep)
  973. struct date *datep;
  974. {
  975. int time, date, tick;
  976. short day, *sp;
  977. char *cp;
  978.  
  979.     _sysdate (0, &time, &date, &day, &tick);
  980.     sp = (short *) &date;
  981.     datep->da_year = *sp++;
  982.     cp = (char *) sp;
  983.     datep->da_mon = *cp++;
  984.     datep->da_day = *cp;
  985. }
  986.  
  987. void
  988. gettime (timep)
  989. struct time *timep;
  990. {
  991. int time, date, tick;
  992. short day;
  993. char *cp;
  994.  
  995.     _sysdate (0, &time, &date, &day, &tick);
  996.     cp = (char *) &time;
  997.     cp++;
  998.     timep->ti_hour = *cp++;
  999.     timep->ti_min = *cp++;
  1000.     timep->ti_sec = *cp;
  1001.     cp = (char *) &tick;
  1002.     cp += 3;
  1003.     timep->ti_hund = *cp;
  1004. }
  1005.  
  1006. int disable ()
  1007. {
  1008. }
  1009.  
  1010. void restore (c)
  1011. char c;
  1012. {
  1013. }
  1014.  
  1015. int istate()
  1016. {
  1017.     return (1);
  1018. }
  1019.  
  1020. int
  1021. spawnvp (mode,path,argv)
  1022. int mode;
  1023. char *path, *argv[];
  1024. {
  1025. int retval, status, w;
  1026. struct sgbuf sbuf;
  1027.  
  1028.         _gs_opt(0, &sbuf);
  1029.         _ss_opt(0, &svbuf);
  1030.     if (UseCurses)
  1031.         endwin();
  1032.     retval = os9exec(os9forkc, path, argv, environ, 0, 0, 3);
  1033.         if (retval)
  1034.         while ((w = wait(&status)) != retval && w != -1)
  1035.             ;
  1036.         _ss_opt(0, &sbuf);
  1037.         if (UseCurses)    {
  1038. #ifdef SCREENSAVER
  1039.             sskick();
  1040. #endif
  1041.             touchwin (ScreenOwner->screen->win);
  1042.             wrefresh (ScreenOwner->screen->win);
  1043.         }
  1044.     return (retval);
  1045. }
  1046.  
  1047. int
  1048. getcbrk()
  1049. {
  1050.     return 0;
  1051. }
  1052.  
  1053. int
  1054. setcbrk(mode)
  1055. int mode;
  1056. {
  1057.     return mode;
  1058. }
  1059.  
  1060.  
  1061. void
  1062. giveup()
  1063. {
  1064. }
  1065.  
  1066. wready ()
  1067. {
  1068. int stat;
  1069.  
  1070.      stat = curses_in->buf_hi_water - curses_in->buf_lo_water;
  1071.      if (!stat)          {
  1072.           stat = _gs_rdy (fileno (stdin));
  1073.           stat = (stat > 0) ? 1 : 0;
  1074.           }
  1075.      return (stat);
  1076. }
  1077.  
  1078.  
  1079. kbraw()
  1080. {
  1081. unsigned char c;
  1082. int ci = -1;
  1083. static char sendaLF = 0;
  1084.  
  1085. #ifdef notagain
  1086.     if (sendaLF)    {
  1087.         sendaLF = 0;
  1088.         return '\l';
  1089.     }
  1090.     sendaLF = 0;
  1091. #endif
  1092.     if (UseCurses)    {
  1093.         if (wready ())
  1094.             ci = wgetch (stdscr);
  1095.         if (ci == KEY_ENTER)    {
  1096.             ci = '\n';
  1097.             sendaLF = 1;
  1098.         }
  1099.         if (ci == KEY_BACKSPACE)
  1100.             ci = '\b';
  1101.         return ci;
  1102.     } else    {
  1103.         if (_gs_rdy(0) < 0)
  1104.             return -1;
  1105.         read(0, &c, 1);
  1106.         if (c == '\n')
  1107.             sendaLF = 1;
  1108.         return c;
  1109.     }
  1110. }
  1111.  
  1112. void *
  1113. mallocw(nb)
  1114. unsigned nb;
  1115. {
  1116.     register void *p;
  1117.  
  1118.     while((p = malloc(nb)) == NULL){
  1119.         sleep (1);
  1120.     }
  1121.     return p;
  1122. }
  1123.  
  1124. void *
  1125. callocw(nelem,size)
  1126. unsigned nelem;    /* Number of elements */
  1127. unsigned size;    /* Size of each element */
  1128. {
  1129.     register unsigned i;
  1130.     register char *cp;
  1131.  
  1132.     i = nelem * size;
  1133.     cp = mallocw(i);
  1134.     memset(cp,0,i);
  1135.     return cp;
  1136. }
  1137.  
  1138. char *
  1139. stpcpy (dest, src)
  1140. char *dest, *src;
  1141. {
  1142.     strcpy (dest, src);
  1143.     return (dest+strlen(src));
  1144. }
  1145.  
  1146.  
  1147. long
  1148. dostounix (d, t)
  1149. struct date *d;
  1150. struct time *t;
  1151. {
  1152.     return 1L;
  1153. }
  1154.  
  1155. int
  1156. stime (t)
  1157. time_t *t;
  1158. {
  1159.     return 0;
  1160. }
  1161.  
  1162.  
  1163. void
  1164. _strtime (str)
  1165. char *str;
  1166. {
  1167. char *cp;
  1168. int k;
  1169. time_t tm;
  1170.  
  1171.     time (&tm);
  1172.     cp = ctime (&tm);
  1173.     cp += 11;
  1174.     for (k = 0; k < 8; k++)
  1175.         *str++ = *cp++;
  1176.     *str = 0;
  1177. }
  1178.  
  1179. void
  1180. screendaemon (i,v1,v2)
  1181. int i;        /* Args not used */
  1182. char *v1;
  1183. void *v2;
  1184. {
  1185.     if (!UseCurses)
  1186.         return;
  1187.     for(;;){
  1188.         kpause(500L);    /* Run displayStatLine every 1/2 second */
  1189.         displayStatLine (0, 1, 0);
  1190.         kpause(500L);    /* and run the rest every second */
  1191.         displayStatLine (0, 0, 0);
  1192. #ifdef SCREENSAVER
  1193.         screensaver ();
  1194. #endif
  1195.     }
  1196. }
  1197.  
  1198. #define SOBUF 256
  1199.  
  1200. /* Printf to Trace session screen or file. Doesn't use ANSI vsprintf */
  1201. int
  1202. traceprintf(fp,fmt,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12)
  1203. FILE *fp;        /* Trace file stream */
  1204. char *fmt;        /* Message format */
  1205. int arg1,arg2,arg3;    /* Arguments */
  1206. int arg4,arg5,arg6;
  1207. int arg7,arg8,arg9;
  1208. int arg10,arg11,arg12;
  1209. {
  1210. int len,withargs;
  1211. char *buf;
  1212.  
  1213.     if(strchr(fmt,'%') == NULLCHAR){
  1214.         /* No args, so we don't need vsprintf() */
  1215.         withargs = 0;
  1216.         buf = fmt;
  1217.         len = strlen(fmt);
  1218.     } else {
  1219.         /* Use a default value that is hopefully longer than the
  1220.          * biggest output string we'll ever print (!)
  1221.          */
  1222.         withargs = 1;
  1223.         buf = mallocw(SOBUF);
  1224.         if((len=sprintf(buf,fmt,arg1,arg2,arg3,arg4,arg5,arg6,arg7,
  1225.             arg8,arg9,arg10,arg11,arg12)) >= SOBUF) {
  1226.             /* It's too late to be sorry. He's dead, Jim. */
  1227.             log(-1,"traceprintf() has exceeded the size of it's buffer. Restarting TNOS.");
  1228.             where_outta_here(2, "traceprintf");
  1229.         }
  1230.     }
  1231.     if (UseCurses && (Current == Trace) && (fp == stdout))
  1232.         cputs(buf);
  1233.     else
  1234.         fprintf (fp, buf);
  1235.  
  1236.     if(withargs)
  1237.         free(buf);
  1238.     return len;
  1239. }
  1240.  
  1241.  
  1242. int16 *
  1243. getstack()
  1244. {
  1245. #asm
  1246.     move.l    a7,d0
  1247.     addq.l    #4,d0
  1248. #endasm
  1249. }
  1250.  
  1251. #asm
  1252. setjmp:    move.l a0,-(a7)
  1253.     movea.l d0,a0
  1254.     move.l 4(a7),(a0)
  1255.     movem.l d0-d7,4(a0)
  1256.     movem.l a1-a7,40(a0)
  1257.     move.l (a7)+,36(a0)
  1258.     moveq.l #0,d0
  1259.     rts
  1260.  
  1261. longjmp:
  1262.     movea.l d0,a0
  1263.     movem.l 4(a0),d0-d7
  1264.     movem.l 40(a0),a1-a7
  1265.     movea.l (a0),a0
  1266.     pea.l (a0)
  1267.     movea.l 36(a0),a0
  1268.     rts
  1269. #endasm
  1270.  
  1271. #endif /* OSK */
  1272.  
  1273.